/*


Dofile containing programs for various purpuses



*/


*** program for conducting and exporting boottest results
cap program drop bexp
program bexp, eclass
	/*
	bexp replaces the the diagonal of e(V) with wild bootstraped p-values ^2
	=> useful if you want to report BS [p-values] below coefs. instead of SEs using outreg with se option
	=> be careful the e(V) remains modified!
	=> place additional boottest options in opt()
	=>  for some reason option julia yields different (weird results)
	=> boottest doesn't work after reghdfe with more than one set of absorbed fixed effects or with absorbed interaction terms.
	=> for some reason using boottest after reghdfe gives error: boottype(wild) not accepted after Maximum Likelihood-based estimation.
	*/
	syntax [,  opt(string)]
	
	local indep_vars: colnames e(b)
	local n_vars: colsof e(b)
	local indep_hypotheses
	foreach var of local indep_vars {

		local indep_hypotheses = "`indep_hypotheses' {`var'}"
	}
	
	// bootstrap (note: you need capture b/c it will throw error for omitted variables => you need to included them for order of the matric below)
	 cap boottest `indep_hypotheses', nograph reps(1000) seed(123) boottype(wild) `opt'   //boottest p-values, 1000 draws, assumes cluster of preceding reg.

	 // check if there is an error thrown OTHER than b/c of omitted variable
	 if _rc !=111 & _rc!=0 {
		di as error "There is an error in boottest"
		exit
	}	
	 
	*Store boottest pvalues in e() matrix
	matrix boot_pval  = J(1,`n_vars',.)
	forval k = 1/`n_vars' { //Loop through predictors, aka matrix columns
		matrix boot_pval[1,`k'] = r(p_`k')
	}
	foreach mat in "boot_pval" {
		matrix colnames `mat' = `indep_vars'	
		estadd matrix `mat' = `mat': `reg_nm'
	}

	* replace diagonal of e(V) with p-values squared
	mat cov =e(V)

	forval k = 1/`n_vars' {
		matrix cov[`k',`k'] = (boot_pval[1,`k'])^2
		if boot_pval[1,`k']==. {
			matrix cov[`k',`k']=999  // 999 instead of missing values (for absorbed vars)
		}
	}
	ereturn repost V=cov
end




*** Program returns string r(stars) with significance stars (* ** ***) when fed t-stat or p-values
cap program drop stars
program stars, rclass
	syntax anything(name=r), stat(string) [coef(numlist max=1 missingok) dec(integer 2) ]
	
	/*
		anything: t or p statistic
		stat:		string 't' or 'p'
		coef: 		coef => if specified, fct returns r(est) with asterisks, e.g., 2.34**
		dec: 		spefify decimal places of coef, default 2
	*/
	
	local N = `:word count `r''
	cap assert `N'==1			// check if only one arg
	if _rc {
		di as error "Only one element allowed as arg"
		exit
	}
	confirm number `r'							// check if arg numeric
	cap assert "`stat'"=="t" | "`stat'"=="p"	// check option correctly specified
	if _rc {
		di as error "Specify 't' or 'p' in option stat()"
		exit
	}
	if "`stat'"=="p" {
		/*
		if `r'<.1	local ask="*"
		if `r'<.05	local ask="**"
		if `r'<.01 	local ask="***"
		*/
		if `r'<.05	local ask="*"
		if `r'<.01	local ask="**"
		if `r'<.001 local ask="***"
		local p=`r'
	}
	else {
		/*
		if `r'>1.64	local ask="*"
		if `r'>1.96	local ask="**"
		if `r'>2.58	local ask="***"	
		*/
		if `r'>1.96	local ask="*"
		if `r'>2.58	local ask="**"
		if `r'>3.29	local ask="***"	
		local t=`r'
	}
	
	
	if "`coef'"!="" local coef: di %12.`dec'f `coef'
	
					return local stars "`ask'"
	if "`coef'"!="" return local est 	"`coef'`ask'"
					return local t `t'
					return local p `p'

end



*** Program to clean .tex Tables exported by 'outreg'
cap program drop cleantex 
program cleantex 	

	syntax anything( name=texfile) [, replace NODISplay]
	
	/*
		Input: .tex table exported by 'outreg'
		Output: cleaned table for Overleaf
		If option REPLACE not specified: tex file with suffix _clean is created
	
	
	*/
	
	 confirm file `texfile'
 	
	tempname fold
	tempname fnew 
	tempfile tmpf
	
	// open oldfile file in read
	file open `fold' using `texfile' , read  text
	file read `fold' line 
	
	// open newfile in write
	qui file open `fnew' using `tmpf' , write text replace
	
	// In outreg, output $N$ is understood by stata as the empty global macro $N 
	cap macro list N 
	if _rc {
		global N "Observations"
	}

	local lno = 0
	while r(eof)==0 {
			local lno `++lno' 
			*di "`line'"
			*di "`lno'"
		local nline="`line'"

		// top rule and bottomrule 
		if `lno'==3 {
			loc nline= ustrregexra("`nline'","\\hline","\\toprule") 
		}
		loc nline= ustrregexra("`nline'","\\hline(?=\\end\{tabular\})","\\bottomrule")
		
		// remove all other \hlines
		loc nline= ustrregexra("`nline'","\\hline","")	
		
		// X => $\times$
		loc nline= ustrregexra("`nline'","\bX\b","`=char(36)'\\times`=char(36)'")
		
		// change % in \% for tex 
		loc nline= ustrregexra("`nline'","(?<!\\)%","\\%")
		
		// remove $ in Observations$
		loc nline= ustrregexra("`nline'","\bObservations\\$","Observations")
		
		// R2 in $R^2$
		loc nline= ustrregexra("`nline'","\bR2\b","`=char(36)' R\^2`=char(36)'")
		
		// remove \begin{..} \end{..} for center/ footnotesize
		loc nline= ustrregexra("`nline'","\\(begin|end)\{(footnotesize|center)\}","")
		
		// remove \noalign{\smallskip}
		loc nline= ustrregexra("`nline'","\\noalign\{\\smallskip\}","")
		
		// clean \midrules 
		if ustrregexm("`nline'","\\midrule")==1 {
			loc nline "\midrule" 
		}
		
		// change \# into $ for (t+1)
		loc nline= ustrregexra("`nline'","\\#(?=t[+-]\d)","`=char(36)' ")
		loc nline= ustrregexra("`nline'","(?<=t[+-]\d)\\#","`=char(36)'")
		
		// remove \\ in {tabular}\\
		loc nline= ustrregexra("`nline'","(?<=\\end\{tabular\})\\\\","")
		
		// WRITE in new file 
		file write 	`fnew' "`nline'"  _n
		
		// display line 
		if "`nodisplay'"=="" {
			di "`nline'"
		}
		// next line in READ
		file read `fold' line
	}
	
	
	 file close `fold'
	 file close `fnew'
	 
	 // clear global macro N 
	 if "$N"=="Observations" {
	 	macro drop N
	 }
	
	// if REPLACE => modify existing table; elso newfile _clean suffix
	if "`replace'"!="" {
	
		copy `tmpf' `texfile', replace
	}	
	else {
		local newfilename = ustrregexra(`"`texfile'"',"(\.tex)","_clean.tex")
		qui copy `tmpf' `newfilename', replace
	}

end	




cap program drop extract_N
program extract_N, rclass
/*
	Little program to extract and return #precincts in control and treatm group
	based on e(sample)
	set 50 or 100 depending on whether event = 100% or 50+% reassgn.

*/
	syntax anything(name=treat)
	
	assert inlist(`treat',50,100)
		
	if `treat'==100 {
		qui distinct(sb_new) if e(sample) & K==0	// count TREAT precincts
		local T = r(ndistinct)
		qui distinct(sb_new) if e(sample) & K==.	// count CTRL precincts
		local C = r(ndistinct)
	}
	else {
		qui distinct(sb_new) if e(sample) & K50==0	// count TREAT precincts
		local T = r(ndistinct)
		qui distinct(sb_new) if e(sample) & K50==.	// count CTRL precincts
		local C = r(ndistinct)		
	}
	
	return local N_T "`T'"
	return local N_C "`C'"
end
	
	
	

	